
class keypad {
  public:
  byte ROWS = 4; //four rows
  byte COLS = 4; //four columns
  byte rowPins[ROWS] = { 8, 9,10,11}; //connect to the row pinouts of the keypad
  byte colPins[COLS] = { 4, 5, 6, 7}; //connect to the column pinouts of the keypad
  char hexaKeys[ROWS][COLS] = {
    {'1','2','3','A'},
    {'4','5','6','B'},
    {'7','8','9','C'},
    {'*','0','#','D'}
  };
  void initial() {
    for(byte i=0;i<ROWS;i++) {
      pinMode(rowPins[i],output);
    }
    for(byte j=0;j<COLS;j++) {
      pinMode(rowPins[i],input);
    }
  }
  
  char get_key() {
    byte row_dat = 0;
    byte col_dat = 0;
    byte row_num = 0;
    byte col_num = 0;
    //scan col
    for(byte i=0;i<ROWS;i++) {
      pinMode(rowPins[i],output);
      digitalWrite(rowPins[i],1<<i);
    }
    for(byte j=0;j<COLS;j++) {
      pinMode(colPins[j],input);
      col_dat[j] = digitalRead(colPins[j]);
    }
    //scan row
    for(byte i=0;i<COLS;i++) {
      pinMode(colPins[i],output);
      digitalWrite(colPins[i],1<<i);
    }
    for(byte j=0;j<ROWS;j++) {
      pinMode(rowPins[j],input);
      row_dat[j] = digitalRead(rowPins[j]);
    }
    row_num = onehot_decode(row_dat);
    col_num = onehot_decode(col_dat);
    if((row_num || col_num) == 0) {
      return 0;
    }
    else {
      return hexaKeys[row_num][col_num];
    }
  }
  
  byte onehot_decode(byte code) {
    switch (code) {
      case   1 : return 0;
      case   2 : return 1;
      case   4 : return 2;
      case   8 : return 3;
      case  16 : return 4;
      case  32 : return 5;
      case  64 : return 6;
      case 127 : return 7;
      default  : return 0;
    }
  }
};

keypad key_pad;
 
void setup(){
  Serial.begin(9600);
}
   
void loop(){
  char key = key_pad.get_key();
   
  if (key != 0){
    Serial.println(key);
  }
  else {
    delay(1);
  }
}
